package com.portal.cwegportal.service;

import com.appcenter.jz.app.CurrentUser;
import com.appcenter.jz.config.ErrorJsonResult;
import com.appcenter.jz.config.HttpResult;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.portal.cwegportal.config.RemoteProperties;
import com.portal.cwegportal.input.maillogininfo.MailLoginInfoInput;
import com.portal.cwegportal.input.usermailaccount.EditUserMailAccountInput;
import com.portal.cwegportal.model.MailInfo;
import com.portal.cwegportal.model.UserMailAccount;
import com.portal.cwegportal.model.api.ApiResult;
import com.portal.cwegportal.model.api.Result;
import com.portal.cwegportal.model.mailapi.MailApiResult;
import com.portal.cwegportal.output.mail.GetMailInfoOutput;
import com.portal.cwegportal.output.usermailaccount.EditUserMailAccountOutput;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import static org.apache.logging.log4j.util.Strings.isBlank;

/*
 * 业务需求：
 * 1 获取当前邮箱的未读邮件数
 * 2 登陆
 * 3 绑定密码
 * 4 重置密码
 */
@EnableConfigurationProperties(RemoteProperties.class)
@Service
public class MailInfoService {
    @Autowired
    com.portal.cwegportal.service.HttpApiService httpApiService;
    @Autowired
    RemoteProperties remoteProperties;
    @Autowired
    ObjectMapper objectMapper;
/**
 *  创建人:王增立
 *  备注: 业务功能    获取未读数 与登陆url public
 *  时间: 2019/4/26 15:03
 *  参数:
 */
    public GetMailInfoOutput getNoReadCounts() throws Exception{
        GetMailInfoOutput output = new GetMailInfoOutput();
        output.setItem(this.getMailNoReadCounts());
        return  output;
    }
    /**
     *  创建人:王增立
     *  备注: 获取邮件未读数
     *  时间: 2019/4/26 15:06
     *  参数: 
     */
    private MailInfo getMailNoReadCounts()throws Exception{
        MailInfo model=new MailInfo();

        Map<String,String> data=Maps.newTreeMap();
        data.put("method","msgnum");
        String sessid=this.getCurrentUserSessid();
        data.put("sessid",sessid);
        String responseJson =  callMailApi(data);

        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MailApiResult result = objectMapper.readValue(responseJson, MailApiResult.class);
        if(result.getResult().equals("ok")){
            model.setNoReadCounts(result.getInfo().getInbox());
            model.setLoginUrl(remoteProperties.getMailLoginUrl()+sessid);
            return model;
        }else {
            throw new ErrorJsonResult("100",result.getError());
        }
    }
    /**
     *  创建人:王增立
     *  备注: 获取配置中的登陆url
     *  时间: 2019/4/26 15:06
     *  参数: 
     */
    private String getMailLoginUrl(){
        return remoteProperties.getMailApiUrl();
    }
    /**
     *  创建人:王增立
     *  备注: 业务功能绑定与重置密码 绑定密码
     *  时间: 2019/4/26 15:06
     *  参数: 
     */
    public boolean BindMailPassword(MailLoginInfoInput input)throws Exception{
        Result emailInfo=this.getUserEmailInfo();
        this.getSessid(emailInfo.getEmail(),input.getItem().getMailPassword());
        return editEmailPassword(input.getItem().getMailPassword(),true,null);
    }
    /**
     *  创建人:王增立
     *  备注: 修改重置密码
     *  时间: 2019/4/26 15:06
     *  参数: 
     */
    public boolean ResetMailPassword(MailLoginInfoInput input)throws Exception{
        //先验证验证码
        if(!validateVerificationCode(input.getItem().getvCode())){
            return false;
        }
        //重置密码
        if(ResetPassword(input.getItem().getMailPassword())){
            try{
                //修改密码
                editEmailPassword(input.getItem().getMailPassword(),false,input.getItem().getvCode());
            }
            catch (ErrorJsonResult ex){
                Result emailInfo=this.getUserEmailInfo();
                //修改失败后 真正邮箱服务器密码回滚
                ResetPassword(emailInfo.getEmailPassword());
                throw  ex;
            }
            //todo 覆盖当前密码 //已不需要覆盖

        }else {
            return  false;
        }
        return true;
    }

    /**
     *  创建人:王增立
     *  备注: 邮箱服务器基础方法 重置密码 邮箱api部分
     *  时间: 2019/4/26 15:06
     *  参数: 
     */
    public  boolean ResetPassword(String newPassword)throws Exception {

        Result emailInfo=this.getUserEmailInfo();
        String email=emailInfo.getEmail();
        String emailUser=email.replaceFirst("@"+remoteProperties.getMailDomain(),"");

        Map<String, String> data = Maps.newTreeMap();
        data.put("method", "user.edited");
        data.put("sessid", getAdminSessid());
        data.put("domain", remoteProperties.getMailDomain());
        data.put("name", emailUser);
        data.put("password", newPassword);
        String responseJson = callMailApi(data, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MailApiResult result = objectMapper.readValue(responseJson, MailApiResult.class);
        if (result.getResult().equals("ok")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     *  创建人:王增立
     *  备注: 获取当前人的sessionId
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    public String getCurrentUserSessid()throws Exception{
        Map<String,String> data=Maps.newTreeMap();
        //return this.getSessid("houxinyu@cwewater.com","Aa123456789");
        Result emailInfo=this.getUserEmailInfo();
        return this.getSessid(emailInfo.getEmail(),emailInfo.getEmailPassword());
    }

    /**
     *  创建人:王增立
     *  备注: 获取管理员Sessid
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    private String getAdminSessid()throws Exception{
        Map<String,String> data=Maps.newTreeMap();
        return this.getSessid(remoteProperties.getMailAdminAccount(),remoteProperties.getMailAdminPassword(),true);
    }
    /**
     *  创建人:王增立
     *  备注: 获取SessionId
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    public String getSessid(String user,String password) throws Exception{
        return  getSessid(user,password,false);
    }
    /**
     *  创建人:王增立
     *  备注: 获取Sessionid
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    public String getSessid(String user,String password,boolean isAdmin) throws Exception{
        Map<String,String> data=Maps.newTreeMap();
        data.put("method","login");
        data.put("user",user);
        data.put("pass",password);

        String responseJson=callMailApi(data,isAdmin);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MailApiResult result = objectMapper.readValue(responseJson, MailApiResult.class);

        if(result.getResult().equals("ok")){
            return  result.getInfo().getSessid();
        }
        else {
            if(result.getError().equals("1"))
            {
                throw new ErrorJsonResult("100","密码不正确");
            }
            else if(result.getError().equals("-1"))
            {
                throw new ErrorJsonResult("100","用户不存在");
            }
            throw new Exception(result.getError());
        }
    }
    /**
     *  创建人:王增立
     *  备注: 调用邮箱api基础方法不使用admin
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    private String callMailApi(Map<String,String> data)throws Exception{
       return callMailApi(data,false);
    }
    /**
     *  创建人:王增立
     *  备注: 调用api基础方法
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    private String callMailApi(Map<String,String> data,boolean isAdmin)throws Exception{
        //配置接口地址 Key Secret
        String mailApiUrl=isAdmin?remoteProperties.getMailAdminApiUrl():remoteProperties.getMailApiUrl();
        String ApiKey=remoteProperties.getMailApiKey();
        String ApiSecret=remoteProperties.getMailApiSecret();
        //基本系统参数
        Map<String,String> postdata= Maps.newTreeMap();
        postdata.put("apikey",ApiKey);
        Long ts = new Date().getTime()/1000;
        String timestamp = String.valueOf(ts);
        postdata.put("timestamp",timestamp);
        //添加接口表单参数
        for (Map.Entry<String,String> entry : data.entrySet()){
           postdata.put(entry.getKey(),entry.getValue());
        }
        //生成签名
        String kvs="";
        for(Map.Entry<String,String> entry : postdata.entrySet()){
            kvs+=entry.getKey()+entry.getValue();
        }
        kvs=ApiSecret+kvs+ApiSecret;
        String sign=MailInfoService.crypt(kvs);
        postdata.put("sign",sign);

        //转换对象开始请求
        Map<String,Object> newPostdata=Maps.newTreeMap();
        newPostdata.putAll(postdata);
        HttpResult httpResult= httpApiService.doPost(mailApiUrl,newPostdata);
        String result=  httpResult.getData();
        return  result;
    }
    /**
     *  创建人:王增立
     *  备注: api邮件签名
     *  时间: 2019/4/26 15:07
     *  参数: 
     */
    private static String crypt(String str) {
        if (str == null || str.length() == 0) {
            throw new IllegalArgumentException("String to encript cannot be null or zero length");
        }
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] hash = md.digest();
            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }
    /**
     *  创建人:王增立
     *  备注: 发送验证码
     *  时间: 2019/4/26 15:08
     *  参数: 
     */
    public boolean sendVerificationCode()throws Exception{
        String method="emailassignverificationcode";
        String ApiUrl=remoteProperties.getAppCenterServiceUrl()+method;
        Object sendData=  new Object(){
            public String appCode=remoteProperties.getDingAppCode();
            public String phone="";
            public String userCode=CurrentUser.getUserCode();
        };

        String sendDataStr=  objectMapper.writeValueAsString(sendData);
        String responseJson=httpApiService.JsonSMS(ApiUrl,sendDataStr);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        ApiResult result = objectMapper.readValue(responseJson, ApiResult.class);
        if(result.isSuccess()){
            return  true;
        }else{
            throw new ErrorJsonResult("100",result.getError().getMessage());
        }
    }
    /**
     *  创建人:王增立
     *  备注: 验证验证码
     *  时间: 2019/4/26 15:08
     *  参数: 
     */
    public boolean validateVerificationCode(String vCode)throws Exception{
        String method="verificationverificationcode";
        String ApiUrl=remoteProperties.getAppCenterServiceUrl()+method;
        Object sendData=  new Object(){
            public String genre="修改邮箱密码";
            public String userCode= CurrentUser.getUserCode();
            public String verificationCode=vCode;
        };
        String sendDataStr = objectMapper.writeValueAsString(sendData);
        String responseJson=httpApiService.JsonSMS(ApiUrl,sendDataStr);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        ApiResult result = objectMapper.readValue(responseJson, ApiResult.class);
        if(result.isSuccess()){
            return  true;
        }else {
            throw new ErrorJsonResult("100",result.getError().getMessage());
        }

    }
    /**
     *  创建人:王增立
     *  备注: 获取当前用户的邮箱信息
     *  时间: 2019/4/26 15:08
     *  参数: 
     */
    public Result getUserEmailInfo() throws Exception{
        String method="getuseremailpassword";
        String ApiUrl=remoteProperties.getAppCenterServiceUrl()+method;
        Object sendData=  new Object(){
            public String userCode=CurrentUser.getUserCode();
        };
        String sendDataStr=  objectMapper.writeValueAsString(sendData);
        String responseJson=httpApiService.JsonSMS(ApiUrl,sendDataStr);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        ApiResult result = objectMapper.readValue(responseJson, ApiResult.class);

        if(result.isSuccess()){
            return result.getResult();
        }else{
            throw new ErrorJsonResult("100",result.getError().getMessage());
        }
    }
    /**
     *  创建人:王增立
     *  备注: 修改密码即绑定密码 在appcenter里
     *  时间: 2019/4/26 15:31
     *  参数: 
     */
    public boolean editEmailPassword(String passWord, boolean noVCode,String vCode)throws Exception{
        String method="editemailpassword";
        String ApiUrl=remoteProperties.getAppCenterServiceUrl()+method;
        Object sendData=  new Object(){
            public String emailPassWord=passWord;
            public String userCode=CurrentUser.getUserCode();
            public boolean inIt=noVCode;
            public String verificationCode=vCode;
        };
        String sendDataStr = objectMapper.writeValueAsString(sendData);
        String responseJson=httpApiService.JsonSMS(ApiUrl,sendDataStr);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        ApiResult result = objectMapper.readValue(responseJson, ApiResult.class);
        if(result.isSuccess()){
            return true;
        }else {
            throw new ErrorJsonResult("100",result.getError().getMessage());
        }
    }
    //endregion


}
